Search Unity

How to preload textures in the scene?

Discussion in 'Scripting' started by zee_ola05, Jun 19, 2014.

  1. zee_ola05

    zee_ola05

    Joined:
    Feb 2, 2014
    Posts:
    166
    I've been tinkering the Profiler a bit and I observed that Unity doesn't load the textures of objects in the scene until it is actually seen by the camera. This causes a lag as I walk around the environment.

    So how do I preload those textures?
     
  2. Hunter_W

    Hunter_W

    Joined:
    May 5, 2014
    Posts:
    57
  3. Hunter_W

    Hunter_W

    Joined:
    May 5, 2014
    Posts:
    57
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Put the desired textures on some objects that are visible to the camera for one frame (the first frame in the game), then destroy the objects. Cover the screen with a blank texture while doing this so it doesn't look ugly—the camera still sees the objects so they still get rendered.

    --Eric
     
  5. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Surely there's a more elegant solution than that?

    @zee_ola05, what kind of "lag" are you talking about? Is it something noticeable, or is it just that you're seeing something in the Profiler? Also, is it Editor only, or do you get it in builds as well?
     
    sp-LeventeLajtai likes this.
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It's not an uncommon technique. Also, it's pretty simple to do and is effective.

    --Eric
     
  7. zee_ola05

    zee_ola05

    Joined:
    Feb 2, 2014
    Posts:
    166
    @Eric5h5 Thank you for your answer. But doesn't Unity have a method like... TextureCache.LoadTexture("texture.png")? Same goes for Unload. Can we use Resources.Load to do this?
     
    sp-LeventeLajtai likes this.
  8. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No, if it had a method like that it would be in the docs. ;) Resources.Load is completely different.

    --Eric
     
  9. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    And it's also rather... stupid, sorry to say.

    All the references are resolved when an a scene is loaded. Unity has no concept of unresolved reference, as far as I know. Loading a resources only when you see it? That's as dumb as it get! I would get massive hang on mobile device any time a new item comes in view!

    Also, it would be terrible if Unity would fill the GPU memory space with texture only when seeing them... That would be terrible as CPU>GPU bandwith is rather limited. When would it remove them? When not seen or when unloaded from script?

    I never encountered something that terrible in all the video game engines I worked on. Do you have any kind of documentation on that rather very unusual behaviour?
     
  10. zee_ola05

    zee_ola05

    Joined:
    Feb 2, 2014
    Posts:
    166
    Ok, is there a way to tell Unity to "cache this texture" via code or via editor? I'm looking for a "non-hackish" solution. If there is none, then I guess I'd just have to do what you said..
     
  11. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    As far as I know it's OpenGL, not Unity. VRAM is virtualized so OpenGL swaps textures in and out as needed.

    --Eric
     
  12. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Really? Why am I not seeing this behaviour on iOS or Mac? Frankly, it's something that make me worry, since pushing large textures only when seen is horrible performance-wise.

    Having written my own renderer, I don't see how a library could withhold resources and inject itself at the right time to push said resourced only when drawn. Hell, the instruction pushed on the GPU stack is so anonymous, you can only know the shader being used because it was the last one transmitted!
     
  13. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Well, that's why I asked earlier whether this was a practical issue or something only noticed when profiling. I've used Unity for many different types of application on many different platforms, and nothing practical like this has ever been noticed.

    Having said that, depending on what "visible" entails, it could simply be that we've never had a use case where it's mattered.

    If this is true I think it calls for someone to write a TexturePreloader component and stick it on the Asset Store for free - something that takes an array of Textures in the Inspector, draws them all once (in a way that they are actually invisible) and then destroys itself.

    Also, I haven't written OpenGL in ages now, but I was under the impression that you could indeed tell it exactly when to push stuff to video RAM. I mean, graphics programming is a performance and optimisation intense field, it doesn't make sense to me that something as important as when a memory copy happens would be out of the coder's hands.
     
  14. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I've seen it fairly often in various games (Unity or otherwise). When objects come into view the first time there can be a slight pause. Nothing major but it's there.

    --Eric
     
  15. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    As have I. But the fact that it happens on some games isn't evidence that it's unavoidable, it's just evidence that those games haven't avoided it.

    I realise you're not saying it's unavoidable, I'm just surprised that it's not avoided.
     
  16. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Are you sure it's not something else?

    Other things can cause a lag when an object come into view;

    - FX being "pre-emited" when viewed
    - Animation catching up and recomputing its bounding
    - Render To Texture feature
    - Lot of tiny objects passing the screen-space occlusion flow at the same time.

    I'm 95% sure that texture resources are not push to the GPU memory space on demand (except for the render to texture surfaces which cost a lot to perform).
     
  17. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Hi Eric, does the Profiler > Rendering reflect the real VRAM usage?

    The cube in the scene use 500MB textures:
    Untitled-1.gif

    Destroying the cube cause the VRAM to lower to some MB's
    Untitled-2.gif

    Would it possible the system/IO cause the jerks loading textures from any device the first time, because the data goes into the system/OS cache. If openGL restart loading the VRAM there is no jerk because stuff will be loaded out of the standard system/OS cache (RAM).

    I expected the VRAM stays at 0.54GB after destroying the object from what you have explained.

    And for example if 2GB of textures are seen by the camera, then 2GB of textures are send each frame to the VRAM?
     
    Last edited: Dec 17, 2017